﻿using Microsoft.Win32;
using System;
using System.Reflection;
using System.Text;
using TopVisionLog;
using System.Runtime.InteropServices;
using System.IO;
using LitJson;
using RestAPI;
using System.Security.Cryptography;

namespace TopVisionVideoStream
{
    public static class Helper
    {
        //===>COM
        //计算机\HKEY_CLASSES_ROOT\Wow6432Node\TypeLib\{F64D1AA2-EA00-4CE8-AA30-270B7A068E90}\1.0\0\win32

        //==>COM
        /// <summary>
        /// 注册表位置根目录
        /// </summary>
        static string comRegistrySubKey = @"TypeLib\";
        /// <summary>
        /// COM ID
        /// </summary>
        static string comLCID = @"{F64D1AA2-EA00-4CE8-AA30-270B7A068E90}";
        /// <summary>
        /// OCX路径
        /// </summary>
        static string ocxSubKey = @"\1.0\0\win32";

        public static string RegComPath = "";
        public static string AppComPath = "";
        public static string zwanFolder = "bin";
        /// <summary>
        /// 
        /// </summary>
        /// <param name="ocxPath"></param>
        /// <returns></returns>
        public static bool CheckCOM(string ocxPath)
        {
            TVLog.WriteLine(">>检查组件");

            try
            {
                using (RegistryKey comSubKey = Registry.ClassesRoot.OpenSubKey(comRegistrySubKey + comLCID))
                {
                    if (comSubKey == null)
                        return false;

                    using (RegistryKey ocxPathSubKey = Registry.ClassesRoot.OpenSubKey(comRegistrySubKey + comLCID + ocxSubKey))
                    {
                        if (ocxPathSubKey == null)
                            return false;

                        string comOCXPath = ocxPathSubKey.GetValue("") as string;

                        string comOCXDictory = comOCXPath.Substring(0, comOCXPath.LastIndexOf(@"\") + 1);
                        comOCXDictory = comOCXDictory.ToLower();
                        RegComPath = comOCXDictory;
                        if (RegComPath.EndsWith(@"\"))
                        {
                            RegComPath = RegComPath.Substring(0, RegComPath.Length - 1);
                        }

                        if (!System.IO.File.Exists(ocxPath))
                            throw new Exception("commponent do not found");
                        String appDictory = ocxPath.Substring(0, ocxPath.LastIndexOf(@"\") + 1);
                        appDictory = appDictory.ToLower();
                        AppComPath = appDictory;

                        var _zwanPath = Path.Combine(appDictory, zwanFolder);

                        TVLog.WriteLine(">>REG:" + RegComPath + "\r\n>>APP:" + _zwanPath);

                        return RegComPath.ToLower().Equals(_zwanPath.ToLower());
                    }
                }
            }
            catch (Exception ex)
            {
                TVLog.WriteLine(">>检查错误:" + ex.Message);

                return false;
            }
        }


        static int iType = 1;
        static double iReport = 1;
        static string pDeliverTime = "1000";
        //static string pReceiverURI = "";
        static string pLocalMsgID = "";
        static string pTMSubject = "";
        static double iFileSeekSize = 0;
        static string tmpMsg = "";


        /// <summary>
        /// 发送消息
        /// </summary>
        /// <param name="destination">目的地</param>
        /// <param name="message">内容</param>
        /// <returns></returns>
        public static bool SendMessage(string pReceiverURI, string message)
        {
            if (string.IsNullOrEmpty(pReceiverURI)) return false;

            var core = Configuration.Core;

            tmpMsg = "Send Message:" + iType + "," + iReport + "," + message + "," + pDeliverTime + "," + pReceiverURI + "," + pLocalMsgID + "," + pTMSubject + "," + iFileSeekSize;

            TVLog.WriteLine(tmpMsg);

            return core.bIMSSendMessage(iType, iReport, message, pDeliverTime, pReceiverURI, pLocalMsgID, pTMSubject, iFileSeekSize) != 0;
        }



        #region 读取配置文件服务器配置

        public static string SOFTDA_CFG = "BASE_CFG";

        public static string SERVER = "SERVER";

        public static string Host;

        private static string defaultIMSSSPort = "1233";

        public static string IMSSSPort = defaultIMSSSPort;

        public static void SetServerIP()
        {
            TVLog.WriteLine("设置服务器IP");
            //InitAppConfig();

            Host = ReadServerIP();

            INIOperation.INIWriteValue(TVVS.IniZwanphone, "BASE_IMS", "IMSSSPort", Helper.IMSSSPort);

#if DEBUG
            Console.WriteLine("服务器IP:" + Host + " IMSSSPort:" + IMSSSPort);
#endif

            RestAPICommon.ServerIP = Host;
        }

        private static string ReadServerIP()
        {
            return GetIP(GetPrivateProfileString(SOFTDA_CFG, SERVER));
        }

        private static string GetIP(string index)
        {
            try
            {
                if (index == "")
                {
                    throw new Exception("配置读取错误:服务器配置为空");
                }

                return GetIP((ServerType)(int.Parse(index)));
            }
            catch (Exception ex)
            {
                TVLog.WriteLine("服务器类型参数不正确:" + ex.Message);

                throw ex;
            }
        }

        private static string GetIP(int index)
        {
            ServerType t = (ServerType)index;

            return GetIP(t);
        }

        private static string GetIP(ServerType serverType)
        {
            TVLog.WriteLine("INI:" + Configuration.iniZwanphone);

            string ip = "";

            RestAPICommon.ServerPort = ":8080";

            Configuration.UploadAddress = "";

            string videoPathHeader = "{0}:{1}/{2}/";

            IMSSSPort = defaultIMSSSPort;

            switch (serverType)
            {
                case ServerType.None:
                    break;
                case ServerType.ZS:
                    break;
                case ServerType.ALI_ZWAN:
                    ip = "42.121.120.234";
                    RestAPICommon.ServerIP = ip;
                    break;
                case ServerType.ALI_TopVision:
                    ip = "106.14.136.31";
                    RestAPICommon.ServerIP = ip;
                    VideosManager.recordPathHeader = string.Format(videoPathHeader, TVVS.ServerUrl, "9002", "nfs");
                    Configuration.UploadAddress = "";
                    break;
                case ServerType.HW_TopTrue:
                    ip = "122.112.226.4";
                    RestAPICommon.ServerIP = ip;
                    VideosManager.recordPathHeader = string.Format(videoPathHeader, TVVS.ServerUrl, "80", "/ty-webapp/tone/zwan/recordpath");
                    Configuration.topvision_api = "http://122.112.226.39:8082/topvision-api/";
                    Configuration.UploadAddress = "app/videostream/uploadFile";
                    Configuration.photoAddress = "";
                    break;
                case ServerType.AMZ_ZZ:
                    ip = "52.193.54.117";
                    RestAPICommon.ServerIP = ip;
                    break;
                case ServerType.Customer_ShangQi:
                    ip = "10.6.128.100";
                    RestAPICommon.ServerIP = ip;
                    break;
                case ServerType.Customer_HeHuang:
                    ip = "218.242.137.201";
                    RestAPICommon.ServerIP = ip;
                    break;
                case ServerType.LOCAL_70:
                    ip = "192.168.2.70";
                    RestAPICommon.ServerIP = ip;
                    VideosManager.recordPathHeader = string.Format(videoPathHeader, TVVS.ServerUrl, "80", "nfs");
                    Configuration.UploadAddress = "";
                    break;
                case ServerType.LOCAL_71:
                    ip = "192.168.2.71";
                    RestAPICommon.ServerIP = ip;
                    break;
                case ServerType.LOCAL_ZL:
                    ip = "192.168.1.100";
                    RestAPICommon.ServerIP = ip;
                    break;
                case ServerType.Customer_Flex_Local:
                    ip = "172.28.198.11";
                    RestAPICommon.ServerIP = ip;
                    break;
                case ServerType.Customer_Flex:
                    ip = "58.211.230.139";
                    RestAPICommon.ServerIP = ip;
                    break;
                case ServerType.LOCAL_ZL2:
                    ip = "10.42.91.6";
                    RestAPICommon.ServerIP = ip;
                    break;
                case ServerType.LOCAL_ZL3:
                    ip = "10.87.112.200";
                    RestAPICommon.ServerIP = ip;
                    break;
                case ServerType.JUXING:
                    ip = "192.168.1.186";
                    RestAPICommon.ServerIP = ip;
                    break;
                case ServerType.Customer_HeHuang2:
                    ip = "111.230.151.199";
                    RestAPICommon.ServerIP = ip;
                    break;
                case ServerType.Topvision_nanjin:
                    ip = "112.80.35.3";
                    RestAPICommon.ServerIP = ip;
                    RestAPICommon.ServerPort = ":9080";
                    VideosManager.recordPathHeader = string.Format(videoPathHeader, TVVS.ServerUrl, "8180", "nfs");
                    break;
                case ServerType.ZWAN_WAN:
                    ip = "222.178.193.83";
                    RestAPICommon.ServerIP = ip;
                    break;
                case ServerType.Juxin:
                    ip = "180.167.253.166";
                    RestAPICommon.ServerIP = ip;
                    RestAPICommon.ServerPort = ":9011";
                    break;
                case ServerType.Jorjin_AMZ:
                    ip = "34.239.56.14";
                    RestAPICommon.ServerIP = ip;
                    break;
                case ServerType.ZhongLi:
                    ip = "124.89.89.29";
                    RestAPICommon.ServerIP = ip;
                    RestAPICommon.ServerPort = ":20017";
                    break;
                case ServerType.Ruantong:
                    ip = "114.115.201.194";
                    break;
                case ServerType.ZhongLi_ZT:
                    ip = "222.90.73.19";
                    RestAPICommon.ServerIP = ip;
                    IMSSSPort = "40085";
                    RestAPICommon.ServerPort = ":40081";
                    break;
                case ServerType.Ruantong2:
                    ip = "49.4.10.79";
                    //RestAPICommon.ServerIP = "49.4.10.129";
                    RestAPICommon.ServerIP = ip;
                    RestAPICommon.ServerPort = ":8099";
                    VideosManager.recordPathHeader = string.Format(videoPathHeader, TVVS.ServerUrl, "80", "nfs");
                    Configuration.topvision_api = "http://49.4.10.79:8099/topvision-api/";
                    break;
                case ServerType.ZhongChe:
                    ip = "47.110.158.100";
                    RestAPICommon.ServerIP = ip;
                    VideosManager.recordPathHeader = string.Format(videoPathHeader, TVVS.ServerUrl, "9002", "nfs");
                    Configuration.UploadAddress = "";
                    break;
                case ServerType.GuoWang:
                    ip = "120.211.156.195";
                    RestAPICommon.ServerIP = ip;
                    IMSSSPort = "1223";
                    RestAPICommon.ServerPort = ":18080";
                    VideosManager.recordPathHeader = string.Format(videoPathHeader, TVVS.ServerUrl, "9002", "nfs");
                    Configuration.UploadAddress = "";
                    break;
                case ServerType.HeBeiGuoWang:
                    ip = "120.211.156.219";
                    RestAPICommon.ServerIP = ip;
                    RestAPICommon.ServerPort = ":18080";
                    VideosManager.recordPathHeader = string.Format(videoPathHeader, TVVS.ServerUrl, "9002", "nfs");
                    Configuration.UploadAddress = "";
                    break;
                case ServerType.WenZhouDianxing:
                    ip = "33.112.8.126";
                    RestAPICommon.ServerIP = ip;
                    RestAPICommon.ServerPort = ":8080";
                    break;
                case ServerType.Topvision_nanjin2:
                    ip = "112.80.35.4";
                    RestAPICommon.ServerIP = ip;
                    RestAPICommon.ServerPort = ":9080";
                    VideosManager.recordPathHeader = string.Format(videoPathHeader, TVVS.ServerUrl, "8180", "nfs");
                    break;
                case ServerType.WuGang:
                    ip = "172.26.68.115";
                    RestAPICommon.ServerIP = ip;
                    VideosManager.recordPathHeader = string.Format(videoPathHeader, TVVS.ServerUrl, "8080", "nfs");
                    Configuration.UploadAddress = "";
                    break;
                case ServerType.WuGangLan:
                    ip = "10.108.48.166";
                    RestAPICommon.ServerIP = ip;
                    VideosManager.recordPathHeader = string.Format(videoPathHeader, TVVS.ServerUrl, "8080", "nfs");
                    Configuration.UploadAddress = "";
                    break;
                case ServerType.WebRTC:
                    ip = "111.229.179.162";
                    RestAPICommon.ServerIP = ip;
                    RestAPICommon.ServerPort = "80";
                    VideosManager.recordPathHeader = string.Format(videoPathHeader, TVVS.ServerUrl, "80", "nfs");
                    Configuration.UploadAddress = "";
                    break;
                default:
                    break;
            }

            TVLog.WriteLine("服务器:" + serverType.ToString() + " IP:" + ip);

            Configuration._ServerType = serverType;

            return ip;
        }

        [DllImport("kernel32")]
        private static extern int GetPrivateProfileString(string section, string key, string default_var, StringBuilder retVal, int buff_size, string filePath);

        private static string GetPrivateProfileString(string section, string key)
        {
            StringBuilder temp = new StringBuilder(255);

            GetPrivateProfileString(section, key, "", temp, 255, Configuration.AppPath + Configuration.iniZwanphone);

            return temp.ToString();
        }

        #endregion


        #region 程序集版本

        public static string GetAssemblyInfoVersion()
        {
            var attributes = Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(AssemblyFileVersionAttribute), true);

            if (attributes.Length > 0)
                return ((AssemblyFileVersionAttribute)attributes[0]).Version;

            return "";
        }

        #endregion


        #region Json工具

        //public static T DicToObject<T>(this Dictionary<string, string> dic)
        //{
        //    return JsonConvert.DeserializeObject<T>(JsonConvert.SerializeObject(dic));
        //}

        //public static T ArrayToObject<T>(this string[] array)
        //{            
        //    Dictionary<string, string> dic = new Dictionary<string, string>();
        //    for (int i = 0; i < array.Length; i++)
        //    {
        //        string[] items = array[i].Split(':');
        //        if (items.Length > 1)
        //            dic[items[0]] = items[1];
        //    }
        //    return dic.DicToObject<T>();
        //}


        public static T ArrayToObject<T>(this string[] array)
        {
            if (array == null || array.Length < 11) return default(T);

            JsonData _jd = new JsonData();

            try
            {
                for (int i = 0; i < array.Length; i++)
                {
                    var _tmp = array[i].Split(':');
                    string _key = _tmp[0];
                    string _value = _tmp[1];
                    _jd[_key] = _value;
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine("QOS : " + ex.Message);
            }

            return JsonMapper.ToObject<T>(_jd.ToJson());
        }

        #endregion


        #region 时间戳

        public static long GetTimeStamp()
        {
            DateTime dt1 = new DateTime(1970, 1, 1);
            long timeStamp = (long)((DateTime.Now - dt1).TotalMilliseconds);
            return timeStamp;
        }

        #endregion


        #region Base64 Helper

        public static string ToBase64(this string str)
        {
            try
            {
                byte[] bytes = Encoding.UTF8.GetBytes(str);
                return Convert.ToBase64String(bytes);
            }
            catch (Exception ex)
            {
                TVLog.WriteLine("ERR ToBase64 : " + ex.Message);
                return "";
            }
        }

        public static string Base64ToString(this string base64Str)
        {
            try
            {
                var bytes = Convert.FromBase64String(base64Str);
                return Encoding.UTF8.GetString(bytes);
            }
            catch (Exception ex)
            {
                TVLog.WriteLine("ERR Base64ToString : " + ex.Message);
                return "";
            }
        }

        #endregion

        /// <summary>
        /// 字符串转MD5
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        public static string ToMD5(this string data)
        {
            byte[] byte1 = Encoding.UTF8.GetBytes(data);
            MD5 md5 = new MD5CryptoServiceProvider();
            byte[] byte2 = md5.ComputeHash(byte1);
            string md5Str = "";
            for (int i = 0; i < byte2.Length; i++)
            {
                md5Str += byte2[i].ToString("x2");
            }
            return md5Str.ToLower();
        }

    }
}
